var SysUtil = {
  scrollBarWidth: null,

  getScrollbarWidth: function () {
    var scrollBarWidth = this.scrollBarWidth;
    if (scrollBarWidth !== null) {
      return scrollBarWidth;
    }

    var outer = document.createElement('div');
    outer.className = 'el-scrollbar__wrap';
    outer.style.visibility = 'hidden';
    outer.style.width = '100px';
    outer.style.position = 'absolute';
    outer.style.top = '-9999px';
    document.body.appendChild(outer);

    var widthNoScroll = outer.offsetWidth;
    outer.style.overflow = 'scroll';

    var inner = document.createElement('div');
    inner.style.width = '100%';
    outer.appendChild(inner);

    var widthWithScroll = inner.offsetWidth;
    outer.parentNode.removeChild(outer);
    scrollBarWidth = widthNoScroll - widthWithScroll;
    this.scrollBarWidth = scrollBarWidth;

    return scrollBarWidth;
  },

  getUser: function () {
    var user = window.sessionStorage.getItem('user');
    if (user !== undefined && user !== null) {
      return new Promise(function (resole) {
        user = JSON.parse(user);
        resole(user);
      });
    }

    var self = this;
    return ajaxRequest('user/getUserName').then(function (user) {
      self.formatUserInfo(user);
      window.sessionStorage.setItem('user', JSON.stringify(user));
      return user;
    });
  },

  formatUserInfo: function (user) {
    var permissionList = user.permissionList;
    permissionList = _.map(permissionList, 'url');
    permissionList = _.filter(permissionList, function (permission) {
      return !permission.endsWith('.html') && !permission.endsWith('.jsp');
    });

    var pageList = user.permissionList;
    pageList = _.map(pageList, 'url');
    pageList = _.filter(pageList, function (page) {
      return page.endsWith('.html') || page.endsWith('.jsp');
    });

    user.pageList = pageList;
    user.permissionList = permissionList;

    var fixedWarehouseCreateUser = user.userId === '3260';
    user.userPagePermission = {
      fixedWarehouseCreateUser: fixedWarehouseCreateUser
    }
  },

  isEmpty: function (value) {
    if (value === null || value === undefined) {
      return true;
    }

    var type = typeof value;
    if (type === 'boolean') {
      return value;
    }

    if (type === 'number') {
      return isNaN(value);
    }

    if (type === 'string') {
      return value === '';
    }

    if (type === 'object') {
      if (_.isArray(value)) {
        return value.length === 0;
      }
      return this.isEmptyObjct(value);
    }

    return false;
  },

  isEmptyObjct: function (object) {
    for (var key in object) {
      return false;
    }
    return true;
  },

  equalsObj: function (oldData, newData, fields) {
    if (oldData === newData) {
      return true;
    }

    if (_.isArray(oldData) && _.isArray(newData)) {
      if (oldData.length !== newData.length) {
        return false;
      }
      for (var i = 0; i < oldData.length; i++) {
        if (!this.equalsObj(oldData[i], newData[i])) {
          return false;
        }
      }
    } else if (typeof oldData === 'object' && typeof newData === 'object') {
      if (_.keys(oldData).length !== _.keys(newData).length) {
        return false;
      }

      if (fields === undefined) {
        for (var key in oldData) {
          if (!this.equalsObj(oldData[key], newData[key])) {
            return false;
          }
        }
      } else {
        for (var i = 0; i < fields.length; i++) {
          var key = fields[i];
          if (!this.equalsObj(oldData[key], newData[key])) {
            return false;
          }
        }
      }
    } else {
      return false;
    }
    return true;
  },

  equalsArray: function (oldData, newData, strict) {
    if (!_.isArray(oldData) || !_.isArray(newData)) {
      throw new Error('data is not array');
    }

    if (oldData.length !== newData.length) {
      return false;
    }

    if (strict) {
      oldData = _.sortBy(oldData);
      newData = _.sortBy(newData);
    }
    return this.equalsObj(oldData, newData);
  },

  getObjectFieldCount: function (object) {
    var count = 0;
    for (var key in object) {
      count++;
    }
    return count;
  },

  getSupplierDropDown: function () {
    return ajaxRequest('putOutNew/getPutoutSupplier', {
      status: 1
    }).then(function (res) {
      var supplierList = res.returnData;
      supplierList = _.map(supplierList, function (supplier) {
        return {
          id: supplier.id,
          supplierName: supplier.supplierName
        };
      });
      return supplierList;
    }).catch(function () {
      return [];
    });
  },

  isPc: function () {
    var userAgentInfo = navigator.userAgent;
    var Agents = ["Android", "iPhone",
      "SymbianOS", "Windows Phone",
      "iPad", "iPod"
    ];
    var flag = true;
    for (var v = 0; v < Agents.length; v++) {
      if (userAgentInfo.indexOf(Agents[v]) > 0) {
        flag = false;
        break;
      }
    }
    return flag;
  },

  setPostData: function (postData, formObj, fields, hasTrim, hasNull) {
    for (var i = 0; i < fields.length; i++) {
      var field = fields[i];
      var value = formObj[field];
      if (typeof value === 'string') {
        if (hasTrim) {
          value = value.trim();
        }
      }

      if (!hasNull) {
        if (value === null || value === undefined || value === '') {
          continue;
        }
      }

      postData[field] = value;
    }
  },

  delNullData: function (obj, fields) {
    for (var i = 0; i < fields.length; i++) {
      var field = fields[i];
      var value = obj[field];
      if (value === null || value === undefined || value === '') {
        delete obj[field];
      }
    }
  },

  getDataByField: function (obj, field, defaultValue) {
    var value = _.get(obj, field);
    if (this.isEmpty(value)) {
      return defaultValue;
    }
    return value;
  },

  formatDate2String: function (time, formatter) {
    if (this.isEmpty(time)) {
      return '';
    }

    if (typeof time === 'string') {
      time = Number(time);
    }
    if (formatter === undefined) {
      formatter = 'YYYY-MM-DD';
    }
    return moment(time).format(formatter);
  },

  formatString2Date: function (time, formatter) {
    if (this.isEmpty(time)) {
      return '';
    }

    if (formatter !== undefined) {
      if (!moment(time, formatter).isValid()) {
        return '';
      }
      return moment(time, formatter).valueOf();
    }
    if (!moment(time).isValid()) {
      return '';
    }
    return moment(time).valueOf();
  },

  formatString2Number: function (obj, fieldList) {
    for (var i = 0; i < fieldList.length; i++) {
      var field = fieldList[i];
      var value = obj[field];
      if (value === null || value === undefined) {
        value = '';
      } else {
        if (typeof value === 'string') {
          if (value !== '') {
            value = Number(value);
          }
        }
      }
      obj[field] = value;
    }
  },

  decimalNumber: function (value, decimal) {
    if (value === null || value === undefined) {
      return '';
    }

    if (decimal === undefined) {
      decimal = 2;
    }
    return _.round(value, decimal);
  },

  getAvgData: function (value1, value2, decimal) {
    if (value2 === 0) {
      return 0;
    }
    var value = value1 / value2;
    if (decimal === undefined) {
      return value;
    }
    return this.decimalNumber(value, decimal);
  },

  getBasePath: function () {
    var pathName = window.document.location.pathname;
    var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
    return projectName;
  },

  formatFormParam: function (obj, hasNull) {
    if (hasNull === undefined) {
      hasNull = true;
    }

    var paramList = [];
    for (var key in obj) {
      var value = obj[key];
      if (!hasNull && this.isEmpty(value)) {
        continue;
      }
      paramList.push(`${key}=${value}`);
    }
    return paramList.join('&');
  },

  getPathParam: function () {
    var search = window.location.search;
    search = search.substring(1);
    if (search === '') {
      return null;
    }

    var paramList = search.split('&');
    var param = {};
    for (var i = 0; i < paramList.length; i++) {
      var paramStr = paramList[i];
      var index = paramStr.indexOf('=');
      if (index === -1) {
        continue;
      }

      var key = paramStr.substring(0, index);
      var value = paramStr.substring(index + 1);
      param[key] = value;
    }

    if (this.isEmptyObjct(param)) {
      return null;
    }
    return param;
  },

  hasPropertyFormPathParam: function (property) {
    var param = this.getPathParam();
    if (param === null) {
      return false;
    }

    var value = param[property];
    return !this.isEmpty(value);
  },

  checkApproval: function (specialRemark, option) {
    if (specialRemark === null) {
      return false;
    }

    if (specialRemark.endsWith('|')) {
      specialRemark = specialRemark.substring(0, specialRemark.length - 1);
    }
    specialRemark = specialRemark.split('|');
    if (specialRemark.length === 0) {
      return false;
    }

    var fields = ['lineNo', 'materialType', 'materialFactory'];
    var fieldLen = fields.length;
    var isOpraterAdd = option.isOpraterAdd;
    for (var i = 0; i < specialRemark.length; i++) {
      var remark = specialRemark[i];
      var startIndex = _.indexOf(remark, '&');
      var endIndex = _.lastIndexOf(remark, '&');
      var remarkObj = {
        lineNo: remark.substring(0, startIndex),
        materialType: remark.substring(startIndex + 1, endIndex),
        materialFactory: remark.substring(endIndex + 1),
      };
      var index = 0;
      for (var j = 0; j < fieldLen; j++) {
        var field = fields[j];
        var remarkValue = remarkObj[field];
        if (isOpraterAdd === 0 && remarkValue === 'all') {
          index = j;
          continue;
        }
        var optionValue = option[field] + '';
        if (remarkValue !== optionValue) {
          break;
        }
        index = j;
      }
      if (index === fieldLen - 1) {
        return true;
      }
    }
    return false;
  },

  getDurationStr: function (time) {
    var workMoment = moment.duration(time);
    var hour = workMoment.asHours();
    hour = Math.floor(hour);
    var minute = workMoment.minutes();
    if (hour === 0) {
      return `${minute}分钟`;
    }
    return `${hour}小时${minute}分钟`;
  },

  arrayRemoveByIndexList: function (array, indexList) {
    return _.remove(array, function (obj, index) {
      return indexList.indexOf(index) !== -1;
    });
  },

  getId: function () {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 32; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[12] = "4";
    s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1);
    var uuid = s.join("");
    return uuid;
  },

  sortDataByField: function (data, field, sortType) {
    if (sortType === undefined) {
      sortType = 'asc';
    }

    var self = this;
    data.sort(function (obj1, obj2) {
      var order = self.sortCompare(obj1, obj2, field);
      if (sortType === 'desc') {
        order = -order;
      }
      return order;
    });
    return data;
  },

  sortDataByColumns: function (data, columns) {
    var self = this;
    data = data.sort(function (obj1, obj2) {
      for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        var sortValue = self.sortCompare(obj1, obj2, column.sortField);
        if (sortValue === 0) {
          continue;
        }

        var sortType = column.sortType;
        if (sortType === 'desc') {
          sortValue = -sortValue;
        }
        return sortValue;
      }
      return 0;
    });

    return data;
  },

  sortCompare: function (obj1, obj2, field) {
    var value1, value2;
    if (field === undefined) {
      value1 = obj1;
      value2 = obj2;
    } else {
      value1 = obj1[field];
      value2 = obj2[field];
    }
    if (typeof value1 === 'string') {
      value1 = value1.trim();
    }
    if (typeof value2 === 'string') {
      value2 = value2.trim();
    }

    if (SysUtil.isEmpty(value1)) {
      value1 = null;
    }
    if (SysUtil.isEmpty(value2)) {
      value2 = null;
    }

    if (value1 === null || value2 === null) {
      if (value1 === value2) {
        return 0;
      }

      if (value1 === null) {
        return 1;
      } else {
        return -1;
      }
    }
    if (typeof value1 === 'string' || typeof value2 === 'string') {
      return value1.localeCompare(value2);
    } else {
      return value1 - value2;
    }
  },

  getMaterialNumberPrecision: function (unitName, defaultPrecision) {
    if (unitName === undefined) {
      throw new Error("单位为空");
    }
    var unitNameArr = ['颗', '粒', '个', '只', '支', '付', '台', '件'];
    if (defaultPrecision === undefined) {
      defaultPrecision = 2;
    }
    if (unitNameArr.indexOf(unitName) > -1) {
      return 0;
    }
    return defaultPrecision;
  },

  hasSameProperty: function (checkSameObj, obj, propertyList) {
    for (var key in checkSameObj) {
      if (propertyList !== undefined) {
        if (propertyList.indexOf(key) === -1) {
          continue;
        }
      }

      if (checkSameObj[key] !== obj[key]) {
        return false;
      }
    }
    return true;
  },

  firstWordUpperCase: function (word) {
    word = word.replace(/(\w)(\w*)/g, function ($0, $1, $2) {
      return $1.toUpperCase() + $2;
    });
    return word;
  },

  getPersonalIncomeTax: function (salary) {
    salary -= 5000;
    if (salary < 0) {
      return 0;
    }
    var taxRateList = [{
      limit: 3000,
      rate: 0.03,
      deduction: 0
    }, {
      limit: 12000,
      rate: 0.1,
      deduction: 210
    }, {
      limit: 25000,
      rate: 0.2,
      deduction: 1410
    }, {
      limit: 35000,
      rate: 0.25,
      deduction: 2660
    }, {
      limit: 55000,
      rate: 0.3,
      deduction: 4410
    }, {
      limit: 80000,
      rate: 0.35,
      deduction: 7160
    }, {
      limit: Infinity,
      rate: 0.45,
      deduction: 15160
    }];
    var currentTaxRate;
    for (var i = 0; i < taxRateList.length; i++) {
      var taxRate = taxRateList[i];
      if (taxRate.limit >= salary) {
        currentTaxRate = taxRate;
        break;
      }
    }

    var tax = salary * currentTaxRate.rate - currentTaxRate.deduction;
    tax = _.round(tax, 2);
    return tax;
  },

  //最大公约数
  getGreatestCommonDivisor: function (a, b) {
    if (b === 0) return a;
    return this.getGreatestCommonDivisor(b, a % b);
  },

  //最小公倍数
  getLowestCommonMultiple: function (a, b) {
    var divisor = this.getGreatestCommonDivisor(a, b);
    var value = a * b / divisor;
    return _.round(value, 0);
  },

  calPrice: function (count, price, type, decimal) {
    if (this.isEmpty(count) || count === 0) {
      return 0;
    }

    if (this.isEmpty(price) || price === 0) {
      return 0;
    }

    if (decimal === undefined) {
      decimal = 2;
    }

    var returnPrice;
    if (type === 'total') {
      returnPrice = _.round(price * count, decimal);
    } else if (type === 'unit') {
      returnPrice = _.round(price / count, decimal);
    }
    return returnPrice;
  },

  tableSetDeptData: function (obj) {
    var materialDeptId = obj.materialDeptId;
    var materialDeptName = obj.materialDeptName;
    if (this.isEmpty(materialDeptName)) {
      materialDeptId = '';
      materialDeptName = '';
    }
    obj.materialDeptId = materialDeptId;
    obj.materialDeptName = materialDeptName;
  },

  formatUnit2px: function (value, unit,hasFloor) {
    if (unit === 'px') {
      return value;
    }

    if (hasFloor === undefined) {
      hasFloor = true;
    }

    var $el = $('<div class="cal-width-div"></div>');
    $el.css({
      width: value + unit
    });
    $('#app').append($el);
    value = $el.width();
    $el.remove();
    if (hasFloor) {
      value = Math.floor(value);
    }
    return value;
  },

  getElRect: function (target) {
    var xy = target.getBoundingClientRect();
    var top = xy.top - document.documentElement.clientTop + document.documentElement.scrollTop,
      bottom = xy.bottom,
      left = xy.left - document.documentElement.clientLeft + document.documentElement.scrollLeft,
      right = xy.right,
      width = xy.width || right - left,
      height = xy.height || bottom - top;
    return {
      top: top,
      right: right,
      bottom: bottom,
      left: left,
      width: width,
      height: height
    };
  }
};
